﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using HYFamilyLibDataManager;
using HYView;

namespace YJKArch.RoomRoofModule
{
	[Regeneration(RegenerationOption.Manual)]
	[Transaction(TransactionMode.Manual)]
	public class CmdDimFloorStruElv : YJKCommandManual
	{
		private FamilySymbol getDimSymbol(string ver, DimType dType)
		{
			FamilySymbol familySymbol = null;
			FamilySymbol result;
			try
			{
				DbCategory dbCategory = FamilyLibDatabase.GetSqliteDB(SubjectType.System, ver).CategoryTable["建筑标记"]["楼板标记"];
				if (dbCategory == null)
				{
					throw new Exception("未能在族库中找到楼板标记族，请检查系统族库！");
				}
				List<DbFamily> allFamilies = dbCategory.GetAllFamilies(false, CheckType.All);
				string b = "";
				if (dType == DimType.ArchStruct)
				{
					b = "标高标记—标高1";
				}
				else if (dType == DimType.Struct)
				{
					b = "标高标记—标高2";
				}
				foreach (DbFamily dbFamily in allFamilies)
				{
					if (dbFamily.Name == b)
					{
						List<FamilySymbol> symbols = dbFamily.Load(this.m_doc).GetSymbols();
						if (symbols.Count > 0)
						{
							familySymbol = symbols[0];
						}
						if (familySymbol == null)
						{
							MessageBox.Show("未能在族库中找到楼板标记族，请检查！", "盈建科提示");
							break;
						}
						break;
					}
				}
				result = familySymbol;
			}
			catch (Exception ex)
			{
				result = familySymbol;
			}
			return result;
		}

		protected override Result YJKExcute(ExternalCommandData cmdData, ref string message, ElementSet elements)
		{
			CmdViewType types = (CmdViewType)11;
			if (SwitchView.SetUsableView(types, cmdData) != Autodesk.Revit.UI.Result.Succeeded)
			{
				return Autodesk.Revit.UI.Result.Failed;
			}
			cmdData.Application.Application.FailuresProcessing += this.OnFailuresProcessing;
			Result result;
			try
			{
				DlgDimFloor instance = DlgDimFloor.GetInstance();
				if (instance.ShowDialog() == DialogResult.OK)
				{
					DimFloorData dimFloorData = instance.DimFloorData;
					FamilySymbol dimSymbol = this.getDimSymbol(cmdData.Application.Application.VersionNumber, dimFloorData.DimType);
					if (dimSymbol == null)
					{
						return Autodesk.Revit.UI.Result.Cancelled;
					}
					if (dimFloorData.SelectType == SelectType.All)
					{
						List<Floor> list = this.SearchFloor();
						if (list.Count <= 0)
						{
							throw new Exception("当前视图中没有找到楼板对象，请检查！");
						}
						using (List<Floor>.Enumerator enumerator = list.GetEnumerator())
						{
							while (enumerator.MoveNext())
							{
								Floor floor = enumerator.Current;
								try
								{
									this.DimFloor(floor, dimSymbol);
								}
								catch
								{
									return Autodesk.Revit.UI.Result.Cancelled;
								}
							}
							goto IL_1C8;
						}
					}
					if (dimFloorData.SelectType == SelectType.Single)
					{
						try
						{
							for (;;)
							{
								FloorFilter floorFilter = new FloorFilter();
								Reference reference = this.m_uiDoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, floorFilter, "请选择楼板对象。");
								Floor floor2 = this.m_doc.GetElement(reference) as Floor;
								this.DimFloor(floor2, dimSymbol, reference.GlobalPoint);
							}
						}
						catch (Exception ex)
						{
							throw ex;
						}
					}
					if (dimFloorData.SelectType == SelectType.Multi)
					{
						try
						{
							for (;;)
							{
								FloorFilter floorFilter2 = new FloorFilter();
								foreach (Reference reference2 in this.m_uiDoc.Selection.PickObjects(Autodesk.Revit.UI.Selection.ObjectType.Element, floorFilter2, "请选择楼板对象。").ToList<Reference>())
								{
									try
									{
										Floor floor3 = this.m_doc.GetElement(reference2) as Floor;
										Level currentViewLevel = AssistFunc.GetCurrentViewLevel(this.m_doc);
										if (GeoUtil.IsEqual(floor3.GetYJKLevel().Elevation, currentViewLevel.Elevation))
										{
											this.DimFloor(floor3, dimSymbol);
										}
									}
									catch
									{
									}
								}
							}
						}
						catch (Exception ex2)
						{
							throw ex2;
						}
					}
				}
				IL_1C8:
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception)
			{
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			return result;
		}

		private List<Floor> SearchFloor()
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc, this.m_doc.ActiveView.Id);
			filteredElementCollector.OfClass(typeof(Floor));
			IEnumerable<Element> enumerable = filteredElementCollector.ToElements();
			List<Floor> list = new List<Floor>();
			Level currentViewLevel = AssistFunc.GetCurrentViewLevel(this.m_doc);
			foreach (Element element in enumerable)
			{
				Floor floor = element as Floor;
				if (floor != null && GeoUtil.IsEqual(floor.GetYJKLevel().Elevation, currentViewLevel.Elevation))
				{
					list.Add(floor);
				}
			}
			return list;
		}

		private void DimFloor(Floor floor, FamilySymbol dim, XYZ location)
		{
			Transaction transaction = new Transaction(this.m_doc, "FloorDim");
			try
			{
				transaction.Start();
				double num = 0.0;
				if (floor != null)
				{
					double elevation = floor.GetYJKLevel().Elevation;
					double num2 = floor.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM).AsDouble();
					foreach (CompoundStructureLayer compoundStructureLayer in floor.FloorType.GetCompoundStructure().GetLayers())
					{
						if ((int)compoundStructureLayer.Function == 1)
						{
							break;
						}
						num += compoundStructureLayer.Width;
					}
					double val = elevation + num2 - num;
					string text = "(" + AssistFunc.feetToMM(val).ToString("0") + ")";
					string text2 = " " + AssistFunc.feetToMM(elevation).ToString("0") + " ";
					floor.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).Set(text);
					floor.get_Parameter(BuiltInParameter.DOOR_NUMBER).Set(text2);
					XYZ floorCenter = this.GetFloorCenter(floor, elevation + num2);
					IndependentTag independentTag = this.m_doc.Create.NewTag(this.m_uiDoc.ActiveView, floor, false, 0, 0, floorCenter);
					independentTag.ChangeTypeId(dim.Id);
					independentTag.TagHeadPosition = location;
				}
				transaction.Commit();
			}
			catch (Exception ex)
			{
				transaction.RollBack();
				throw ex;
			}
		}

		private void DimFloor(Floor floor, FamilySymbol dim)
		{
			Transaction transaction = new Transaction(this.m_doc, "FloorDim");
			try
			{
				transaction.Start();
				double num = 0.0;
				if (floor != null)
				{
					double elevation = floor.GetYJKLevel().Elevation;
					double num2 = floor.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM).AsDouble();
					foreach (CompoundStructureLayer compoundStructureLayer in floor.FloorType.GetCompoundStructure().GetLayers())
					{
						if ((int)compoundStructureLayer.Function == 1)
						{
							break;
						}
						num += compoundStructureLayer.Width;
					}
					double val = elevation + num2 - num;
					string text = "(" + AssistFunc.feetToMM(val).ToString("0") + ")";
					string text2 = " " + AssistFunc.feetToMM(elevation).ToString("0") + " ";
					floor.get_Parameter(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS).Set(text);
					floor.get_Parameter(BuiltInParameter.DOOR_NUMBER).Set(text2);
					XYZ floorCenter = this.GetFloorCenter(floor, elevation + num2);
					if (floorCenter != null)
					{
						IndependentTag independentTag = this.m_doc.Create.NewTag(this.m_uiDoc.ActiveView, floor, false, 0, 0, floorCenter);
						if (independentTag != null)
						{
							independentTag.ChangeTypeId(dim.Id);
						}
					}
				}
				transaction.Commit();
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException ex)
			{
				transaction.RollBack();
				throw ex;
			}
		}

		private XYZ GetFloorCenter(Floor f, double dElevation)
		{
			XYZ result = null;
			double num = 0.0;
			double num2 = 0.0;
			List<XYZ> list = new List<XYZ>();
			foreach (Line curve in ElementAssistFunc.GetElementEdges(this.m_uiApp, this.m_doc, f))
			{
				XYZ hyendPoint = curve.GetEndPoint(0);
				if (GeoUtil.IsEqual(dElevation, hyendPoint.Z))
				{
					list.Add(hyendPoint);
				}
				hyendPoint = curve.GetEndPoint(1);
				if (GeoUtil.IsEqual(dElevation, hyendPoint.Z))
				{
					list.Add(hyendPoint);
				}
			}
			AssistFunc.CompressArray(list);
			if (list.Count == 0)
			{
				return null;
			}
			result = list.First<XYZ>();
			GeoUtil.polyCentriod(list, ref result, ref num, ref num2);
			return result;
		}

		public void OnFailuresProcessing(object sender, FailuresProcessingEventArgs e)
		{
			FailuresAccessor failuresAccessor = e.GetFailuresAccessor();
			string transactionName = failuresAccessor.GetTransactionName();
			IList<FailureMessageAccessor> failureMessages = failuresAccessor.GetFailureMessages();
			if (failureMessages.Count == 0)
			{
				e.SetProcessingResult((FailureProcessingResult)0);
				return;
			}
			if (transactionName.Equals("FloorDim"))
			{
				foreach (FailureMessageAccessor failureMessageAccessor in failureMessages)
				{
					failuresAccessor.DeleteWarning(failureMessageAccessor);
				}
				e.SetProcessingResult((FailureProcessingResult)1);
				return;
			}
			e.SetProcessingResult((FailureProcessingResult)0);
		}
	}
}
